package com.web.kdl.service.site;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.web.kdl.common.result.CommonResult;
import com.web.kdl.dao.report.Report1Dao;
import com.web.kdl.daoV2.matrix.MatrixDao;
import com.web.kdl.daoV2.site.SiteDao;
import com.web.kdl.daoV2.siteWheel.SiteWheelDao;
import com.web.kdl.entity.flywheelDataAnalysis.FlywheelDataAnalysis;
import com.web.kdl.entity.matrix.Matrix;
import com.web.kdl.entity.site.Site;
import com.web.kdl.entity.sitewheel.SiteWheel;
import com.web.kdl.pojo.Vo.EnergyDataVo;
import com.web.kdl.pojo.Vo.SysEleVo;
import com.web.kdl.pojo.Vo.SysWorkStatusVo;
import com.web.kdl.pojo.Vo.SystemBaseVo;
import com.web.kdl.pojo.Vo.site.SiteMonVo;
import com.web.kdl.pojo.dto.FlywheelMainDto;
import com.web.kdl.pojo.Bo.MatrixBo;
import com.web.kdl.pojo.form.SiteAddForm;
import com.web.kdl.pojo.form.SiteUpdateForm;
import com.web.kdl.service.createTable.ControlTable;
import com.web.kdl.service.createTable.TableDataType;
import com.web.kdl.service.createTable.TableType;
import com.web.kdl.service.flywheel.FlyWheelService;
import com.web.kdl.util.RedisKeyUtil;
import com.web.kdl.util.RedisUtils;
import com.web.kdl.util.TableNameUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.*;

/**
 * @Author： shulibin
 * @Date： 2025/7/25 8:23
 * @Describe：
 */
@Service
public class SiteServiceImpl implements SiteService{


    @Resource
    SiteDao siteDao;

    @Resource
    MatrixDao matrixDao;

    @Resource
    SiteWheelDao siteWheelDao;
    @Resource
    Report1Dao report1Dao;

    @Resource
    FlyWheelService flyWheelService;

    @Resource
    JdbcTemplate jdbcTemplate;
    @Resource
    RedisUtils redisUtils;

    @Override
    @Transactional(rollbackFor = Exception.class)
        public int addSite(SiteAddForm form) {
        LambdaQueryWrapper<Site> siteLambdaQueryWrapper = new LambdaQueryWrapper<>();
        siteLambdaQueryWrapper.eq(Site::getSumSite, form.getSiteName());
        Site existSite = siteDao.selectOne(siteLambdaQueryWrapper);
        if (existSite != null) {
            return 0;
        }
        Site site = form.toSite();
         return siteDao.insert(site);
    }

    @Override
    public int deleteByIds(List<String> siteIds) {
        siteWheelDao.delete(new LambdaQueryWrapper<SiteWheel>().eq(SiteWheel::getSiteId, siteIds));
        return siteDao.deleteBatchIds(siteIds);
    }

    @Override
    public List<Site> getAllSize() {
        return siteDao.selectList(null);
    }

    @Override
    public Boolean updateSite(SiteUpdateForm form) {
        Site site = siteDao.selectById(form.getId());
        site.setSumSite(form.getSiteName());
        BeanUtils.copyProperties(form, site);
        int i = siteDao.updateById(site);
        return i>0;
    }

    @Override
    public SystemBaseVo getSystemInfo() {
        SystemBaseVo resultVo = new SystemBaseVo();

        // 查询的key集合
        List<Matrix> matrixs = matrixDao.selectList(null);
        for (Matrix matrix : matrixs)
        {
            for ( int i = 1; i <= matrix.getWheelNumber(); i++)
            {
                String redisKey = RedisKeyUtil.getRedisKey(matrix.getId(), i);
                // 对应 matrix id 下的 flywheel i 飞轮数据
                List<FlywheelDataAnalysis> list = redisUtils.getMap(redisKey, FlywheelDataAnalysis.class);
                resultVo.addDto(list);
            }
        }
        //       WITH RankedData AS (
        //        SELECT
        //        device_name AS deviceName,
        //        data_value AS dataValue,
        //        unit AS unit,
        //        time,
        //        ROW_NUMBER() OVER (PARTITION BY device_name ORDER BY time DESC) as rn
        //        FROM ${tableName}
        //        WHERE device_name IN ('系统容量', '总放电量', '总充电量')
        //        )
        //        SELECT
        //        deviceName,
        //        dataValue,
        //        unit,
        //        time
        //        FROM RankedData
        //        WHERE rn = 1

        // 查询站点下的所有阵列
//        List<String> tableList = getAllSiteDataName(TableDataType.DAY);
//        tableList.forEach(tableName -> {
//            List<FlywheelMainDto> dataDto = report1Dao.getWheelForSite(tableName);
//            resultVo.addDto(dataDto);
//        });
    return resultVo;
    }

    @Override
    public List<EnergyDataVo> getSystemEleInfo() {
        List<List<EnergyDataVo>> allFlywheelData = new ArrayList<>();
        List<String> tableList = getAllSiteDataName(TableDataType.DAY);
        tableList.forEach(tableName -> {
            List<EnergyDataVo> flywheelEle = flyWheelService.getAllFlywheelEleCount(tableName);
            allFlywheelData.add(flywheelEle);
        });
        // 历史数据
        List<EnergyDataVo> sysEleVos = aggregateEnergyData(allFlywheelData);

        // 当前天 是否是新月的第一天
        // 若不是 将最新数据替换 sysEleVos 中的 对应月份
        // 若是新月 第一天 则将数据加入
        EnergyDataVo sysEleVo = new EnergyDataVo();
        // 统计当前 上次飞轮列表的 总充电量和 总放电量
        List<Matrix> matrixs = matrixDao.selectList(null);
            for (Matrix matrix : matrixs)
            {
                for ( int i = 1; i <= matrix.getWheelNumber(); i++)
                {
                    String redisKey = RedisKeyUtil.getRedisKey(matrix.getId(), i);
                    //  存储的是每个飞轮 当前时间节点的最新数据
                    List<FlywheelDataAnalysis> list = redisUtils.getMap(redisKey, FlywheelDataAnalysis.class);
                    if (list == null || list.isEmpty()) {
                        continue;
                    }
                    sysEleVo.setTime(list.get(0).getMonth());
                    for (FlywheelDataAnalysis flywheelData : list) {
                        if ( flywheelData.getDeviceName().equals("总充电量")){
                            sysEleVo.Add(flywheelData.getDataValue(),0);
                        }else if (flywheelData.getDeviceName().equals("总放电量")){
                            sysEleVo.Add(0,flywheelData.getDataValue());
                        }
                    }
                }
            }
        if (sysEleVo.getTime() == null) {
                return sysEleVos;
        }
        if (!ObjectUtils.isEmpty(sysEleVos)){
            existingRecord(sysEleVos, sysEleVo);
        }
        return sysEleVos;
    }

    public static void existingRecord(List<EnergyDataVo> sysEleVos, EnergyDataVo sysEleVo) {
        Optional<EnergyDataVo> existingRecord = sysEleVos.stream()
                .filter(vo -> vo.getTime().equals(sysEleVo.getTime()))
                .findFirst();

        if (existingRecord.isPresent()) {
            // 如果存在，移除旧记录并添加新记录（实现覆盖效果）
            sysEleVos.remove(existingRecord.get());
            sysEleVos.add(sysEleVo);
        } else {
            // 如果不存在，直接添加新记录
            sysEleVos.add(sysEleVo);
        }
    }

    public static List<EnergyDataVo> aggregateEnergyData(List<List<EnergyDataVo>> flywheelEle) {
        // 使用Map按月份聚合数据，key是月份，value是该月份的总电量
        Map<String, EnergyDataVo> monthlyAggregatedData = new HashMap<>();

        // 遍历所有飞轮的数据
        for (List<EnergyDataVo> singleFlywheelData : flywheelEle) {
            // 遍历单个飞轮的每月数据
            for (EnergyDataVo monthlyData : singleFlywheelData) {
                String month = monthlyData.getTime();

                // 如果该月份还未记录，初始化
                if (!monthlyAggregatedData.containsKey(month)) {
                    monthlyAggregatedData.put(month, new EnergyDataVo(month, 0.0, 0.0));
                }
                // 累加当前飞轮该月份的电量
                EnergyDataVo aggregated = monthlyAggregatedData.get(month);
                aggregated.setCharge(aggregated.getCharge() + monthlyData.getCharge());
                aggregated.setDischarge(aggregated.getDischarge() + monthlyData.getDischarge());
            }
        }
        // 将Map转换为List并按时间排序（如果需要）
        List<EnergyDataVo> result = new ArrayList<>(monthlyAggregatedData.values());
        // 如果需要按时间排序可以取消下面的注释
         result.sort(Comparator.comparing(EnergyDataVo::getTime));

        return result;
    }
    @Override
    public List<SiteMonVo> getSystemEvent() {
        ArrayList<SiteMonVo> sysMonitorsVos = new ArrayList<>();
        List<String> tableList = getAllSiteName(TableType.ALERT);
        tableList.forEach(tableName -> {
            List<SiteMonVo> siteMonMsg = report1Dao.getSiteMonMsg(tableName);
            sysMonitorsVos.addAll(siteMonMsg);
        });
        return sysMonitorsVos;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult deleteById(String id) {
        Site site = siteDao.selectById(id);
        if(site.getWheelNumber() > 0){
            return CommonResult.error("请先删除该站点下的所有飞轮");
        }
        // 删除该站点下的所有其他信息
//        int siteWheelStatus = siteWheelDao.delete(new LambdaQueryWrapper<SiteWheel>().eq(SiteWheel::getSiteId, id));
        int siteStatus = siteDao.deleteById(id);
        if(siteStatus<=0) {
            throw new RuntimeException("站点删除失败");
        }
        return CommonResult.success("站点删除成功");
    }

    @Override
    public Site getSiteById(int siteId) {
        return siteDao.selectById(siteId);
    }
    @Override
    public  List<Matrix> getMatrixBySiteName(String siteName) {
        Site site = siteDao.selectByName(siteName);
        LambdaQueryWrapper<Matrix> eq = new LambdaQueryWrapper<Matrix>().eq(Matrix::getSiteId, site.getId());
        List<Matrix> matrices = matrixDao.selectList(eq);
        return matrices;
    }

    @Override
    public List<String> getAllSiteName(TableType type) {
        List<String> table = new ArrayList<>();
        // 构建 需要查询的 飞轮表列表
        List<MatrixBo> matrixBos = matrixDao.selectMatrixTable();
        for (MatrixBo matrixBo : matrixBos)
        {
            for(int i = 1; i <= matrixBo.getFlywheelSerial(); i++){
                String tableName = "";
                if(type == TableType.STATUS){
                     tableName = TableNameUtils.getStatusTableName(matrixBo.getSiteName(), matrixBo.getMatrixName(), i);
                    table.add(tableName);
                }else if(type == TableType.ALERT){
                    tableName = TableNameUtils.getAlertTableName(matrixBo.getSiteName(), matrixBo.getMatrixName(), i);
                    table.add(tableName);
                }
            }
            if(type == TableType.STATUS){
                table.add(TableNameUtils.getControlStatusTableName(matrixBo.getSiteName(), matrixBo.getMatrixName()));
            }else if(type == TableType.ALERT){
                table.add(TableNameUtils.getControlAlertTableName(matrixBo.getSiteName(), matrixBo.getMatrixName()));
            }
        }
        return table;
    }

    @Override
    public List<String> getAllSiteDataName(TableDataType type) {
        List<String> table = new ArrayList<>();
        // 构建 需要查询的 飞轮表列表
        List<MatrixBo> matrixBos = matrixDao.selectMatrixTable();
        for (MatrixBo matrixBo : matrixBos)
        {
            for(int i = 1; i <= matrixBo.getFlywheelSerial(); i++){
                String tableName = TableNameUtils.getDataTableName(matrixBo.getSiteName(), matrixBo.getMatrixName(), i,type);
                table.add(tableName);
            }
        }
        return table;
    }

    @Override
    public SysWorkStatusVo getSystemWorkStatus() {
        List<Site> sites = siteDao.selectList(null);
        SysWorkStatusVo sysWorkStatusVo = new SysWorkStatusVo();
        sysWorkStatusVo.setRunNum(sites.size());
        sysWorkStatusVo.setStandbyNum(0);
        sysWorkStatusVo.setAlertNum(0);
        sysWorkStatusVo.setFlywheelNum(sites.size());
        return sysWorkStatusVo;
    }
}
